Ext.namespace("Dudley");
Ext.namespace("Dudley.lims");

Dudley.lims.LabOligo = function() {

    var myAOData = [];
    var aoligoForm = {};
    var aoligoPanel = {};
    var aoligoHash = null;
    var aoligoCount = null;
    var aoligoMaxNum = null;
    var aoligoStore = null;
    var aoligoLoaded = false;
    function initAOStore(failedCb, callback) {
        loadAOSearchResult(0, null, callback);
    }

    function loadAOSearchResult(index, searchResultJSON, callback) {
    	aoligoStore = loadSolrSearchResult("AO", getOligoPagingColumns(), laboligoSolrTranslator, index, searchResultJSON);
     	aoligoStore.load({params:{start:0, limit:10}}, callback());		             
    }

    function goSearch(index, aoligoSearchInput, aoligoSearchOption) {
        if (aoligoSearchInput == '') {
        	aoligoSearchInput = 'AO';
        }
        aoligoSearchInput = checkWildcard(aoligoSearchInput);
        var searchUrl = getSolrSearchUrl(getLuceneTerm(aoligoSearchOption, aoligoSearchInput), 1000,
        "loligoKey,loligoName,loligoNotes,loligoGene,loligoSequence,loligoYName,loligoProject,loligoModification,loligoPurification,loligoConcentration,loligoOrderedBy,loligoComments");
        var searchWin = getSearchLoadingWindow("ao-");
        searchWin.on("show", function () {
            var sb = Ext.getCmp("ao-search-statusbar");
            sb.showBusy();
        });
        searchWin.show();
        Ext.Ajax.request({
            url: searchUrl,
            method: "GET",
            success: function(response) {
                var searchResultObj = Ext.util.JSON.decode(response.responseText);
                console.log("LabOligo Result count:" + searchResultObj.response.numFound);                
                loadAOSearchResult(index, searchResultObj.response, function() {
                    Ext.getDom("sample-search-result-list").innerHTML = "";
                    Ext.getDom("yo-form").innerHTML = "";
                    searchWin.close();
                    renderAOSearchResult();
                });
            },
            failure: function() {
                eventManager.fireStatusMessageEvent({ text: "Search Results failed for url:" + searchUrl, level: "error" });
            }
        });
    }

    function loadAOPanel() {
    	var aoligoSearchForm = getSearchForm("aoligoSearchButtonId", "aoligoSearchInputId", null);
        Ext.getCmp("aoligoSearchButtonId").addListener("click", function(){
			goSearch(0, Ext.getCmp("aoligoSearchInputId").getValue(), "loligoFields");		
	   });		
        var tbarButtons = [
            {
                id: 'showAOSearchResultsId',
                name: 'showAOSearchResults',
                disabled: true,
                text: '<--Search Results',
                icon: "images/back-green.png",
                cls:'x-btn-text-icon',
                listeners: {click:
                        function() {
                            Ext.getDom("yo-form").innerHTML = "";
                            renderAOSearchResult();
                        }
                }
            },
            {
                id: 'searchAllAOId',
                name: 'searchAllAO',
                disabled: false,
                text: 'View All Records',
                icon: "images/search-blue.png",
                cls:'x-btn-text-icon',
                listeners: {click:
                        function() {
                            Ext.getDom("yo-form").innerHTML = "";
                            goSearch(0, 'AO', 'loligoKey');
                        }
                }
            },
            {
                id: 'createNewAOId',
                name: 'createNewAO',
                text: 'Create New AO',
                icon: "images/add-green.png",
                cls:'x-btn-text-icon',
                listeners: {click:
                        function() {
                            Dudley.lims.LabOligo.loadNewAO();
                        }
                }
            }
        ];
        aoligoPanel = new Ext.Panel({
            id: "aoligoPanelId",
            autoHeight: true,
            border: true,
            renderTo: "yad-panel",
            title: "Lab Oligo",
            header: false,
            tbar: tbarButtons,
            items: aoligoSearchForm
        });
        aoligoPanel.on("activate", function () {
            Ext.getDom("yo-panel").innerHTML = "";
            Ext.getDom("yo-form").innerHTML = "";
            Ext.getDom("sample-search-result-list").innerHTML = "";
            if (aoligoLoaded == false) {
                aoligoLoaded = true;
                goSearch(0, 'AO', 'loligoKey');
            }
            renderAOSearchResult();
        });
    }

    function postAOStrain(createNew) {
        var oligoKey = Ext.getCmp("aoligoKeyId").getValue();
        var labOligoJson = new Object();
        labOligoJson["loligoName"] = Ext.getCmp("aoligoNameId").getValue();
        labOligoJson["loligoKey"] = oligoKey;
        labOligoJson["loligoYName"] = Ext.getCmp("aoligoYNameId").getValue();
        labOligoJson["loligoNotes"] = Ext.getCmp("aoligoNotesId").getValue();
        labOligoJson["loligoSequence"] = Ext.getCmp("aoligoSequenceId").getValue();
        labOligoJson["loligoGene"] = Ext.getCmp("aoligoGeneId").getValue();
        labOligoJson["loligoProject"] = Ext.getCmp("aoligoProjectId").getValue();
        labOligoJson["loligoModification"] = Ext.getCmp("aoligoModificationId").getValue();
        labOligoJson["loligoPurification"] = Ext.getCmp("aoligoPurificationId").getValue();
        labOligoJson["loligoConcentration"] = Ext.getCmp("aoligoConcentrationId").getValue();
        labOligoJson["loligoOrderedBy"] = Ext.getCmp("orderedById").getValue();
        var labOligoCallback = function() {
            limsadmin_obj["limsadminLOligoCount"] = aoligoCount; 
            limsadmin_obj['limsadminLOligoMaxNum'] = aoligoMaxNum;
            postSolrUpdates(limsadmin_obj, function(){
                Ext.Msg.alert('Info', "New DeletionOligo " + oligoKey + ' Added Successfully');
                Ext.getDom("yo-form").innerHTML = "";
                Ext.getDom("sample-search-result-list").innerHTML = "";
                goSearch(0, oligoKey, "loligoKey");
            });
        };
        if (!createNew) {
            labOligoCallback = function() {
                Ext.Msg.alert('Info', oligoKey + ' Updated Successfully');
                Ext.getDom("sample-search-result-list").innerHTML = "";
                var searchResultsButton = Ext.getCmp("showAOSearchResultsId");
                searchResultsButton.disable();
            };
        }
        postSolrUpdates(labOligoJson, labOligoCallback);
    }

    function getOCInfo() {
        return "The OligoCalculator calculates Tm based on 0.195M monovalent cation (salt) concentration equal to 1x SSC. For calculating melting temperature (MT) values of oligonucleotides (10 to 50) " +
               "at different monovalent cation concentrations, the formula given below is used. Using the Oligocalculator and the formula, you can calculate the Tm of your favourite " +
               "oligonucleotide amplification primers eg in the Promega PCR buffer (which contains 0.05M monovalent cations) or the Tm of your DIG-labelled oligonucleotide probes which " +
               "are usually used with 0.975M monovalent cations (5x SSC).Required MT= Known MT + 16.6log (required salt concentration / 0.195M), " +
               "where the Known MT is calculated from 0.195M using the OligoCalculator." + "Javascript script code adapted from Eugen Buehler";
    }
    function loadCreateAOStrain(aoligoHash, callback) {
        var createNew = true;
        var buttons = [
            {
                id: 'createButton',
                name: 'createButton',
                text: 'Create',
                listeners: {click:
                        function() {
                            if (validateCreateUpdateOligo('AO')) {
                                postAOStrain(createNew);
                            }
                        }
                }
            }
        ];
        var blatLink = "";
        var blastLink = "";
        var oligoCalc = "";
        if (aoligoHash != null) {
            //http://www.ncbi.nlm.nih.gov/blast/Blast.cgi?CMD=Web&PAGE=Nucleotides&DATABASE=nr&QUERY=555TT
            //blat http://genome.ucsc.edu/cgi-bin/hgBlat?command=start&org=S.+cerevisiae&db=sacCer2&hgsid=194506313&userSeq=TTTTTAFDA
            //http://mbcf.dfci.harvard.edu/docs/oligocalc.html
            //OligoCalculator was written in Javascript by Eugen Buehler
            //http://genome.ucsc.edu/cgi-bin/hgBlat?command=start&org=S.+cerevisiae&userSeq=AATTAATTAATTAATTAATT&type=DNA
            blatLink = '<a href="' + 'http://genome.ucsc.edu/cgi-bin/hgBlat?command=start&org=S.+cerevisiae&type=DNA&userSeq='
                    + aoligoHash.sequence + '" target="_blank">UCSC BLAT</a>';
            blastLink = '<a href="' + 'http://www.ncbi.nlm.nih.gov/blast/Blast.cgi?CMD=Web&PAGE=Nucleotides&DATABASE=nr&QUERY='
                    + aoligoHash.sequence + '" target="_blank">NCBI BLAST</a>';
            //oligoCalc = '<a href="http://mbcf.dfci.harvard.edu/docs/oligocalc.html" target="_blank">Oligo Calculator(copy sequence)</a>';
            oligoCalc = '<A HREF="javascript:Dudley.lims.LabOligo.calculate(\'' + aoligoHash.sequence
                    + '\')">Calculator</A>';
            if (aoligoHash.genotype != undefined && aoligoHash.genotype == 'Record Deleted') {
                buttons = [];
            } else {
                buttons = [
                    {
                        id: 'updateAOButtonId',
                        name: 'updateAOButton',
                        text: 'Update',
                        listeners: {click:
                                function() {
                                    if (validateCreateUpdateOligo('AO')) {
                                        postAOStrain(!createNew);
                                    }
                                }
                        }
                    },
                    {
                        id: 'deleteAOButtonId',
                        name: 'deleteAOButton',
                        text: 'Delete',
                        //disabled: true,
                        listeners: {click:
                                function() {
                                    var deleteUrl = "/addama-rest/dudley-sample/path/datasource/AO/" + aoligoHash.name + "/annotations/?JSON={deleteaoligo:true}";
                                    Ext.Msg.confirm('Message', "Please confirm that you want to delete " + aoligoHash.name + "", function(btn) {
                                        if (btn == 'yes') {
                                            Ext.Ajax.request({
                                                url: deleteUrl,
                                                method: "POST",
                                                success: function() {
                                                    Ext.Msg.alert(aoligoHash.name + " deleted, AO Strains Reloading...");
                                                    goSearch(0, '*', 'All');
                                                },
                                                failure: function() {
                                                    eventManager.fireStatusMessageEvent({ text: "Delete Failed for " + aoligoHash.name, level: "error" });
                                                }
                                            });
                                        }
                                    });
                                }
                        }
                    }
                ];
            }
        } else {
            aoligoHash = new Object();
            var aoligoMaxInt = parseInt(aoligoMaxNum);
            aoligoMaxInt = aoligoMaxInt + 1;
            var aoligoCountInt = parseInt(aoligoCount);
            aoligoCountInt = aoligoCountInt + 1;
            aoligoCount = aoligoCountInt + "";
            aoligoHash.name = 'AO' + aoligoMaxInt;
            aoligoMaxNum = aoligoMaxInt + "";
        }
        aoligoForm = new Ext.form.FormPanel({
            id: 'aoligoForm',
            method: 'POST',
            autoHeight: true,
            autoScroll: true,
            border: true,
            buttonAlign: 'left',
            buttons: buttons,
            items: [
                new Ext.form.FieldSet({
                    autoHeight: true,
                    border: false,
                    items: [
                        new Ext.form.TextField({
                            id: "aoligoKeyId",
                            fieldLabel: "Key",
                            name: "aoligoKey",
                            value: aoligoHash.name,
                            width: 500,
                            readOnly: true,
                            allowBlank: false,
                            listeners: {
                                render: function(c) {
                                    Ext.QuickTips.register({
                                        target: c,
                                        title: '',
                                        text: 'System generated unique identifier'
                                    });
                                }
                            }
                        }),
                        new Ext.form.TextField({
                            id: "aoligoNameId",
                            fieldLabel: "Alias",
                            name: "aoligoName",
                            value: aoligoHash.oligoName,
                            width: 500,
                            allowBlank: false,
                            listeners: {
                                render: function(c) {
                                    Ext.QuickTips.register({
                                        target: c,
                                        title: '',
                                        text: 'Describe gene alias name and relative position of the primer within the gene (ex:A, B, C or D)'
                                    });
                                }
                            }
                        }),
                        new Ext.form.TextField({
                            id: "aoligoYNameId",
                            fieldLabel: "Y Name",
                            name: "aoligoYName",
                            value: aoligoHash.yName,
                            width: 500,
                            allowBlank: true,
                            listeners: {
                                render: function(c) {
                                    Ext.QuickTips.register({
                                        target: c,
                                        title: '',
                                        text: 'Systematic gene name'
                                    });
                                }
                            }
                        }),
                        new Ext.form.TextField({
                            id: "aoligoNotesId",
                            fieldLabel: "Notes",
                            name: "aoligoNotes",
                            value: aoligoHash.notes,
                            width: 500,
                            allowBlank: true,
                            listeners: {
                                render: function(c) {
                                    Ext.QuickTips.register({
                                        target: c,
                                        title: '',
                                        text: 'PCR sizes in the following order: A_D_deletion, A_KanB_deletion, <br>D_KanC_deletion, A_D_wildtype, A_B_wildtype, C_D_wildtype'
                                    });
                                }
                            }
                        }),
                        //http://www.ncbi.nlm.nih.gov/blast/Blast.cgi?CMD=Web&PAGE=Nucleotides&DATABASE=nr&QUERY=555TT
                        //blat http://genome.ucsc.edu/cgi-bin/hgBlat?command=start&org=S.+cerevisiae&db=sacCer2&hgsid=194506313&userSeq=TTTTTAFDA
                        //http://mbcf.dfci.harvard.edu/docs/oligocalc.html
                        new Ext.form.TextField({
                            id: "aoligoSequenceId",
                            labelSeparator: '',
                            fieldLabel: "Sequence<br>" + blatLink + "<br>" + blastLink + "<br>" + oligoCalc,
                            name: "aoligoSequence",
                            value: aoligoHash.sequence,
                            width: 500,
                            allowBlank: true,
                            listeners: {
                                render: function(c) {
                                    Ext.QuickTips.register({
                                        target: c,
                                        title: '',
                                        text: 'sequence of the oligo 5� to 3�, Oligo Calculator adapted ' + '<a href="http://mbcf.dfci.harvard.edu"'
                                                + ' target="_blank">Molecular Biology Core Facilities</a>' + getOCInfo()
                                    });
                                }
                            }
                        }),
                        new Ext.form.TextField({
                            id: "aoligoGeneId",
                            fieldLabel: "Gene",
                            name: "aoligoGene",
                            value: aoligoHash.gene,
                            width: 500,
                            allowBlank: true,
                            listeners: {
                                render: function(c) {
                                    Ext.QuickTips.register({
                                        target: c,
                                        title: '',
                                        text: 'Gene alias'
                                    });
                                }
                            }
                        }),
                        new Ext.form.TextField({
                            id: "aoligoProjectId",
                            fieldLabel: "Project",
                            name: "aoligoProject",
                            value: aoligoHash.project,
                            width: 500,
                            allowBlank: true,
                            listeners: {
                                render: function(c) {
                                    Ext.QuickTips.register({
                                        target: c,
                                        title: '',
                                        text: 'Yeast Deletion Collection confirmation'
                                    });
                                }
                            }
                        }),
                        new Ext.form.TextField({
                            id: "aoligoModificationId",
                            fieldLabel: "Modification",
                            name: "aoligoModification",
                            value: aoligoHash.modification,
                            width: 500,
                            allowBlank: true,
                            listeners: {
                                render: function(c) {
                                    Ext.QuickTips.register({
                                        target: c,
                                        title: '',
                                        text: 'Indicate any non nucleotide changes (ex: biotin,fluorophore, modified base �)'
                                    });
                                }
                            }
                        }),
                        new Ext.form.TextField({
                            id: "aoligoPurificationId",
                            fieldLabel: "Purification",
                            name: "aoligoPurification",
                            value: aoligoHash.purification,
                            width: 500,
                            allowBlank: true,
                            listeners: {
                                render: function(c) {
                                    Ext.QuickTips.register({
                                        target: c,
                                        title: '',
                                        text: 'Specify purification method of oligo synthesis (ex: Desalt, HPLC, PAGE �)'
                                    });
                                }
                            }
                        }),
                        new Ext.form.TextField({
                            id: "aoligoConcentrationId",
                            fieldLabel: "Concentration",
                            name: "aoligoConcentration",
                            value: aoligoHash.concentration,
                            width: 500,
                            allowBlank: false,
                            listeners: {
                                render: function(c) {
                                    Ext.QuickTips.register({
                                        target: c,
                                        title: '',
                                        text: 'Indicate the concentration and solvent of the stock solution '
                                    });
                                }
                            }
                        }),
                        new Ext.form.TextField({
                            id: "orderedById",
                            fieldLabel: "Ordered by",
                            value: aoligoHash.orderedBy,
                            width: 500,
                            allowBlank: true,
                            listeners: {
                                render: function(c) {
                                    Ext.QuickTips.register({
                                        target: c,
                                        title: '',
                                        text: 'Name of the person that ordered the oligo'
                                    });
                                }
                            }
                        })
                    ]
                })
            ]
        });
        callback();

    }

    function AOSearch() {
        renderAOSearchResult();
    }

    function renderAOSearchResult() {
        var searchResultsButton = Ext.getCmp("showAOSearchResultsId");
        if (searchResultsButton != null || searchResultsButton != undefined) {
            searchResultsButton.disable();
        }        
        var mytbar = [
            {
                id: 'laboligo2CSVId',
                text: 'Export2CSV',
                icon: "images/check-green.png",
                cls:'x-btn-text-icon',
                tooltip: 'Export search results to csv',
                listeners: {click:
                        function() {
                            Dudley.lims.LabOligo.toCSV();
                        }
                }
            }
        ];
        var searchResultsGrid = new Ext.grid.GridPanel({
            id: "aoligoSearchResultsId",
            store: aoligoStore,
            columns: getOligoSearchColumnHeaders(),
            stripeRows: true,
            autoHeight: true,
            width: 800,
            title: 'Lab Oligo',
            renderTo: "sample-search-result-list",
            bbar: new Ext.PagingToolbar({
                pageSize: 10,
                store: aoligoStore,
                displayInfo: true,
                displayMsg: 'Displaying strains {0} - {1} of {2}',
                emptyMsg: "No strains to display"
            }),
            tbar: mytbar
        });
        searchResultsGrid.on("celldblclick", function (g, ri, ci, e) {
            var searchResultsButton = Ext.getCmp("showAOSearchResultsId");
            searchResultsButton.enable();
            aoligoHash = new Object();
            populateOligoJson(aoligoHash, g);
            
            loadCreateAOStrain(aoligoHash, function() {
                aoligoFormRender();
            });
        });
    }

    function aoligoFormRender() {
        Dudley.lims.samplemgr.getHousingPanel().activate(aoligoPanel);
        Ext.getDom("sample-search-result-list").innerHTML = "";
        Ext.getDom("yo-form").innerHTML = "";
        aoligoForm.render("yo-form");
    }
    
    function setLoligoAdmin(jsonObj){
    	limsadmin_obj =  jsonObj;
    	aoligoCount = jsonObj.limsadminLOligoCount;
                        aoligoMaxNum = jsonObj.limsadminLOligoMaxNum;                       
                        aoligoHash = null;
                        Ext.getCmp("showAOSearchResultsId").enable();
                        loadCreateAOStrain(aoligoHash, function() {
                            Ext.getDom("sample-search-result-list").innerHTML = "";
                            Ext.getDom("yo-form").innerHTML = "";
                            aoligoForm.render("yo-form");
                        });
     }                   


    // public
    return {
        initAO: function(failedCB) {
            initAOStore(failedCB, function() {
                eventManager.fireStatusMessageEvent({ text: "Finishing init AOStore", level: "info" });
            });
        },

        calculate: function(seq) {
            var myCalculations = calculateOligo(seq);
            var calculationspanel = new Ext.form.FormPanel({
                baseCls: 'x-plain',
                labelWidth: 100,
                defaultType: 'textfield',
                items: [
                    {
                        fieldLabel: 'Length',
                        name: 'length',
                        value: seq.length
                    },
                    {
                        fieldLabel: 'Melting Temp &#176C',
                        name: 'mt',
                        value: myCalculations.MT
                    },
                    {
                        fieldLabel: 'GC Content%',
                        name: 'gc',
                        value: myCalculations.GC
                    },
                    {
                        fieldLabel: 'Molecular Weight daltons g/M',
                        name: 'mw',
                        value: myCalculations.MW
                    },
                    {
                        fieldLabel: 'OD nanoMolar pmol/ml',
                        name: 'od',
                        value: myCalculations.OD
                    },
                    {
                        xtype: 'textarea',
                        hideLabel: true,
                        readOnly: true,
                        name: 'msg',
                        value: getOCInfo(),
                        anchor: '100% -53'  // anchor width by percentage and height by raw adjustment
                    }
                ]
            });
            var ocWin = new Ext.Window({
                title: 'OligoCalculator',
                width: 300,
                height: 400,
                autoScroll: true,
                modal: true,
                bodyStyle: 'padding:2px;',
                items: [calculationspanel],
                layout: 'fit'
            });
            ocWin.show();
        },

        getAOPanel: function() {
            loadAOPanel();
            return aoligoPanel;
        },

        getAOStore: function() {
            return aoligoStore;
        },

        loadNewAO: function() {
            Ext.getDom("yo-form").innerHTML = "";

            getSolrLimsAdmin(setLoligoAdmin);
        },
        loadSearchResult: function() {
            Ext.getDom("sample-search-result-list").innerHTML = "";
            renderAOSearchResult();
        },
        toCSV: function() {
            exportOligos(myAOData, "loligo");
        } ,
        setArrayData: function(data) {
                    myAOData = data;
         }

    };
}();
